#pragma once

#include <cstdlib>
#include <cstdio>
#include <unistd.h>

#include <doca_error.h>
#include <doca_log.h>
#include <glog/logging.h>

#include "dpa_common.h"
#include "common_unit.h"

doca_error_t kernel_launch(struct dpa_resources *resources)
{
	struct doca_mmap_obj host_mmap_obj;
	void * send_ptr = CommonUtils::prepare_host_memory(10);
	for (int i = 0; i < 8; ++i) {
		((int64_t *)send_ptr)[i] = 555;
	}

	host_mmap_obj.mmap_type = MMAP_TYPE_CPU;
	host_mmap_obj.doca_dpa = resources->pf_dpa_ctx;
	host_mmap_obj.doca_device = resources->pf_doca_device;
	host_mmap_obj.permissions = DOCA_ACCESS_FLAG_LOCAL_READ_WRITE | DOCA_ACCESS_FLAG_RDMA_WRITE |
				    DOCA_ACCESS_FLAG_RDMA_READ | DOCA_ACCESS_FLAG_RDMA_ATOMIC | DOCA_ACCESS_FLAG_PCI_READ_WRITE;
	host_mmap_obj.memrange_addr = send_ptr;
	host_mmap_obj.memrange_len = 64;

	doca_error_t cur_doca_err = doca_mmap_obj_init(&host_mmap_obj);
	if (cur_doca_err != DOCA_SUCCESS) {printf ("error!\n"); fflush(stdout);}

	struct doca_sync_event *comp_event = NULL;
	uint64_t comp_event_val = 10;
	const unsigned int num_dpa_threads = 4;
	doca_error_t result;

	result = create_doca_dpa_completion_sync_event(resources->pf_dpa_ctx,
						       resources->pf_doca_device,
						       &comp_event,
						       NULL);
	if (result != DOCA_SUCCESS) {
		LOG(INFO) << "create sync_event failed";
	}

	printf ("before send to kernel, send_ptr = %ld\n", ((int64_t*)send_ptr)[0]);

	result = doca_dpa_kernel_launch_update_set(resources->pf_dpa_ctx,
						   NULL,
						   0,
						   comp_event,
						   comp_event_val,
						   num_dpa_threads,
						   &hello_world,
						   host_mmap_obj.dpa_mmap_handle, 
						   (uint64_t)send_ptr);
	if (result != DOCA_SUCCESS) {
		LOG(INFO) << "kernel_launch failed";
	}

	result = doca_sync_event_wait_gt(comp_event, comp_event_val - 1, SYNC_EVENT_MASK_FFS);
	printf ("after send to kernel, send_ptr = %ld\n", ((int64_t*)send_ptr)[0]);

	return result;
}

class DocaSdkUnit{
	
};